package com.hujifang.elasticsearch.utils;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

public final class StringUtils {
	
	
	private StringUtils() {

	}
	
	public static String getObjectToString(final Object obj) {
		return (null != obj ? obj.toString() : "");
	}

	public static String getStringValue(final String inStr) {
		return (isNullString(inStr)) ? "" : inStr;
	}

	public static String getObjectStringValue(final Object obj, final String defaultStr) {
		if (obj == null) {
			if (defaultStr != null) {
				return defaultStr;
			} else {
				return "";
			}
		} else {
			return String.valueOf(obj);
		}
	}
	
	public static String getObjectStringValue(final Object obj) {
		if (obj == null) {
				return "";
		} else {
			String value = String.valueOf(obj);
			if(isNullString(value) || "null".equalsIgnoreCase(value)){
				return "";
			}
			return String.valueOf(obj);
		}
	}

	/**
	 * Check if the input string is null.
	 * 
	 * @param inStr
	 * @return boolean value indicating if the string is null
	 */
	public static boolean isNullString(final String inStr) {
		if (inStr == null || inStr.trim().equals("")) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * @Title: isNullObject 
	 * @Description: 检查一个对象是否为空对象 
	 * @return boolean    返回类型 true：空对象 false：非空对象
	 * @throws
	 */
	public static boolean isNullObject(final Object obj) {
		return isNullString(getObjectStringValue(obj));
	}

	/**
	 * Converts a hexadecimal string to a byte array.
	 * 
	 * @param hexStr
	 *            Input hexadecimal string.
	 * @return Byte array.
	 * @throws Exception
	 */
	public static byte[] hexToBytes(String hexStr) throws Exception {
		if (hexStr == null) {
			return null;
		}
		if (hexStr.length() % 2 != 0) {
			throw new Exception("Length of data is not equal to even number");
		}
		byte[] rtnBytes = new byte[hexStr.length() / 2];

		for (int i = 0; i < hexStr.length() / 2; i++) {
			rtnBytes[i] = (byte) Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
		}
		return rtnBytes;
	}

	/**
	 * Converts a byte array to string.
	 * 
	 * @param data
	 *            Input byte array.
	 * @return String
	 */
	public static String hexToString(byte[] data) {
		if (data == null) {
			return "";
		}
        StringBuffer sb = new StringBuffer(data.length * 2);
		for (int i = 0; i < data.length; i++) {
			String hex = Integer.toHexString(0xFF & data[i]);
			if (hex.length() == 1) {
				sb.append('0');
			}
			sb.append(hex);
		}
		return sb.toString().toUpperCase();
	}

	/**
	 * Parse a string into a series of string tokens using the specified
	 * delimiter.
	 * 
	 * @param str
	 * @param splitChar
	 * @return Array of string token
	 */
	public static String[] split(String str, char splitChar) {
		if (str == null) {
			return null;
		}
		if (str.trim().equals("")) {
			return new String[0];
		}
		if (str.indexOf(splitChar) == -1) {
			String[] strArray = new String[1];
			strArray[0] = str;
			return strArray;
		}

		ArrayList<String> list = new ArrayList<String>();
		int prevPos = 0;
		for (int pos = str.indexOf(splitChar); pos >= 0; pos = str.indexOf(splitChar, (prevPos = (pos + 1)))) {
			list.add(str.substring(prevPos, pos));
		}
		list.add(str.substring(prevPos, str.length()));

		return list.toArray(new String[list.size()]);
	}

	/**
	 * Parse a string into a series of string tokens using the specified
	 * delimiter.
	 * 
	 * @param str
	 *            Input string
	 * @param delim
	 *            The string delimiter.
	 * @return Array of string tokens.
	 */
	public static String[] tokenize(String str, String delim) {
		String[] strs = null;
		if (str != null) {
			StringTokenizer tokens;
			if (delim == null) {
				tokens = new StringTokenizer(str);
			} else {
				tokens = new StringTokenizer(str, delim);
			}
			strs = new String[tokens.countTokens()];
			for (int i = 0; i < strs.length && tokens.hasMoreTokens(); i++) {
				strs[i] = tokens.nextToken();
			}
		}
		return strs;
	}

	/**
	 * Parse a string into a series of string tokens according to fixed length
	 * and return tokenized string array.
	 * 
	 * @param str
	 *            Input string
	 * @param fixedLength
	 *            The length at which the string is tokenized.
	 * @return Array of string tokens.
	 */
	public static String[] tokenize(String str, int fixedLength) {
		String[] strs = null;
		if (str != null && fixedLength > 0) {
			ArrayList<String> list = new ArrayList<String>();
			for (int i = 0; i < str.length(); i += fixedLength) {
				int next = i + fixedLength;
				if (next > str.length()) next = str.length();
				list.add(str.substring(i, next));
			}
			strs = list.toArray(new String[] {});
		}
		return strs;
	}

	/**
	 * Convert the input string to String encoded in UTF16LE format.
	 * 
	 * @param input
	 * @return String encoded in UTF16LE format
	 * @throws IOException
	 */
	public static String toUTF16LEString(String input) throws IOException {
		if (input == null || input.length() == 0) {
			return input;
		}

		byte[] b = input.getBytes("UTF-16LE");
		return hexToString(b);
	}

	/**
	 * Left padding the string with the specified padding character upto the specified length.
	 * @param inStr Input string
	 * @param length Padding length
	 * @param paddingChar Padding character
	 * @return Padding string
	 */
	public static String leftPad(String inStr, int length, char paddingChar) {
		if (inStr.length() == length) return inStr;

		StringBuffer outStr = new StringBuffer();
		for (int i = inStr.length(); i < length; i++) {
			outStr.append(paddingChar);
		}
		outStr.append(inStr);

		return outStr.toString();
	}

	/**
	 * Right padding the string with the specified padding character upto the specified length.
	 * @param inStr Input string
	 * @param length Padding length
	 * @param paddingChar Padding character
	 * @return Padding string
	 */
	public static String rightPad(String inStr, int length, char paddingChar) {
		if (inStr.length() == length) return inStr;

		StringBuffer outStr = new StringBuffer();
		outStr.append(inStr);

		for (int i = inStr.length(); i < length; i++) {
			outStr.append(paddingChar);
		}

		return outStr.toString();
	}

	/**
	 * Adds leading zeros to the given String to the specified length. Nothing
	 * will be done if the length of the given String is equal to or greater
	 * than the specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param len
	 *            The length of the target string.
	 * @return The String after adding leading zeros.
	 */
	public static String addLeadingZero(String s, int len) {
		return addLeadingCharacter(s, '0', len);
	}

	/**
	 * Adds leading spaces to the given String to the specified length. Nothing
	 * will be done if the length of the given String is equal to or greater
	 * than the specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param len
	 *            The length of the target string.
	 * @return The String after adding leading spaces.
	 */
	public static String addLeadingSpace(String s, int len) {
		return addLeadingCharacter(s, ' ', len);
	}

	/**
	 * Adds specified leading characters to the specified length. Nothing will
	 * be done if the length of the given String is equal to or greater than the
	 * specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param c
	 *            The leading character(s) to be added.
	 * @param len
	 *            The length of the target string.
	 * @return The String after adding the specified leading character(s).
	 */
	public static String addLeadingCharacter(String s, char c, int len) {
		if (s != null) {
			StringBuffer sb = new StringBuffer();
			int count = len - s.length();
			for (int i = 0; i < count; i++) {
				sb.append(c);
			}
			sb.append(s);
			return sb.toString();
		} else {
			return null;
		}
	}

	/**
	 * Removes leading zeros from the given String, if any.
	 * 
	 * @param s
	 *            The source string.
	 * @return The String after removing leading zeros.
	 */
	public static String removeLeadingZero(String s) {
		return removeLeadingCharacter(s, '0');
	}

	/**
	 * Removes leading spaces from the given String, if any.
	 * 
	 * @param s
	 *            The source string.
	 * @return The String after removing leading spaces.
	 */
	public static String removeLeadingSpace(String s) {
		return removeLeadingCharacter(s, ' ');
	}

	/**
	 * Removes specified leading characters from the given String, if any.
	 * 
	 * @param s
	 *            The source string.
	 * @param c
	 *            The leading character(s) to be removed.
	 * @return The String after removing the specified leading character(s).
	 */
	public static String removeLeadingCharacter(String s, char c) {
		if (s != null) {
			int len = s.length();
			int i = 0;
			for (i = 0; i < len; i++) {
				if (s.charAt(i) != c) {
					break;
				}
			}
			if (i > 0) {
				return s.substring(i);
			} else {
				return s;
			}
		} else {
			return null;
		}
	}

	/**
	 * Appends zeros to the given String to the specified length. Nothing will
	 * be done if the length of the given String is equal to or greater than the
	 * specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param len
	 *            The length of the target string.
	 * @return The String after appending zeros.
	 */
	public static String appendZero(String s, int len) {
		return appendCharacter(s, '0', len);
	}

	/**
	 * Appends spaces to the given String to the specified length. Nothing will
	 * be done if the length of the given String is equal to or greater than the
	 * specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param len
	 *            The length of the target string.
	 * @return
	 * 				The String after appending spaces.
	 */
	public static String appendSpace(String s, int len) {
		return appendCharacter(s, ' ', len);
	}

	/**
	 * Appends specified characters to the given String to the specified length.
	 * Nothing will be done if the length of the given String is equal to or
	 * greater than the specified length.
	 * 
	 * @param s
	 *            The source string.
	 * @param c
	 *            The character(s) to be appended.
	 * @param len
	 *            The length of the target string.
	 * @return
	 * 		The String after appending the specified character(s).
	 */
	public static String appendCharacter(String s, char c, int len) {
		if (s != null) {
			StringBuffer sb = new StringBuffer().append(s);
			while (sb.length() < len) {
				sb.append(c);
			}
			return sb.toString();
		} else {
			return null;
		}
	}

	/**
	 * Replaces all the occurences of a search string in a given String with a
	 * specified substitution.
	 * 
	 * @param text
	 *            The String to be searched.
	 * @param src
	 *            The search String.
	 * @param tar
	 *            The replacement String.
	 * @return The result String after replacing.
	 */
	public static String replace(String text, String src, String tar) {
		StringBuffer sb = new StringBuffer();

		if (text == null || src == null || tar == null) {
			return text;
		} else {
			int size = text.length();
			int gap = src.length();

			for (int start = 0; start >= 0 && start < size;) {
				int i = text.indexOf(src, start);
				if (i == -1) {
					sb.append(text.substring(start));
					start = -1;
				} else {
					sb.append(text.substring(start, i)).append(tar);
					start = i + gap;
				}
			}
			return sb.toString();
		}
	}
	
    /**
     * Converting object to String
     * 
     * @param obj the converting object
     * @return
     */
	public static String toString(Object obj) {
		if (null == obj) {
			return null;
		} else {
			return obj.toString();
		}
	}

	/**
	 * Calculate the MD5 checksum of the input string
	 * @param inString Input string
	 * @return MD5 checksum of the input string in hexadecimal value
	 */
	public static String md5sum(String inString) {
		MessageDigest algorithm = null;

		try {
			algorithm = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException nsae) {
			System.err.println("Cannot find digest algorithm");
			return null;
		}

		byte[] defaultBytes = inString.getBytes();
		algorithm.reset();
		algorithm.update(defaultBytes);
		byte messageDigest[] = algorithm.digest();
		return hexToString(messageDigest);
	}

	
	public static boolean isNotEmpty(String outstr){ 
		if(outstr!=null&&outstr.trim().length()>0){
			return true;
		}
		return false;
	}
	
//	public static String urlEncode(String str) {
//		if (null == str) {
//			str = "";
//		}
//		try {
//			return URLEncoder.encode(str, Constants.CHARSET_GB2312);
//		} catch (UnsupportedEncodingException e) {
//			e.printStackTrace();
//			return str;
//		}
//	}
//
//	public static String urlDecode(String str) {
//		if (null == str) {
//			str = "";
//		}
//		try {
//			return URLDecoder.decode(str, Constants.CHARSET_GB2312);
//		} catch (UnsupportedEncodingException e) {
//			e.printStackTrace();
//			return str;
//		}
//	}
		
	public static String inputStream2String(InputStream in) throws IOException {
		StringBuffer out = new StringBuffer();
		byte[] b = new byte[4096];
		for (int n; (n = in.read(b)) != -1;) {
			out.append(new String(b, 0, n));
		}
		return out.toString();
	}
	
	public static boolean isNullMap(Map<?,?> map){
		Set<?> set=map.keySet();
		Iterator<?> iterable=set.iterator();
		while(iterable.hasNext()){
			Object obj=map.get(iterable.next());
			if(null==obj || obj.equals(null)){
				return false;
			}
		}
		return true;
	}
	
	public static long stringTolong(String args,long def){
		if(isNullString(args)){
			return def;
		}
		try {
			return Long.valueOf(args);
		} catch (Exception e) {
			return def;
		}
	}
	
	public static String trim(String str) {
        return str == null ? null : str.trim();
    }
	
		
	/**
	 * 判断是否为null或空字符串
	 * @param o
	 * @return
	 */
	public static boolean isEmpty(Object o){
		if(o == null){
			return true;
		}
		if(o instanceof String){
			return ((String)o).trim().isEmpty();
		}else{
			return o.toString().trim().isEmpty();
		}
	}
	
	/**
	 * 将对象转化为字符窜
	 * @param o
	 * @return
	 */
	public static String obj2str(Object o){
		return o!=null ?  o.toString() : null;
	}
	
	public static final String toStr2(int x){
        return x<10?"0"+x:""+x;
    }
	
	/**
	 * 将对象转化为字符窜
	 * @param obj
	 * @param defaultValue
	 * @return
	 */
	public static String obj2str(Object obj,String defaultValue){
		return obj!=null ?  obj.toString() : defaultValue;
	}
	
	/**
	 * 将对象转化为int类型的数
	 * @param o
	 * @return
	 */
	public static final int obj2int(Object o)
	{
		return obj2int(o,0);
	}
	
	/**
     * 从一个对象(Number,String)得到一个整数
     * @param  o  Number,String 类型的对象
    */
	public static final int obj2int(Object o,int defaultValue){
	    if( o instanceof Number )
			return ((Number)o).intValue();
		if( o instanceof String ){
            String s = ((String)o).trim();
			try {
				return Integer.parseInt(s);
			} catch( Exception ex ){
				
			}
            try {
                return Double.valueOf(s).intValue();
            } catch( Exception ex ){
            	
            }
		}
		return defaultValue;
	}
	
	/**
	 * 将对象转化为boolean类型
	 * @param o
	 * @return
	 */
	public static final boolean obj2bool(Object o)
	{
		return obj2bool(o,false);
	}
	public static final boolean obj2bool(Object o,boolean defaulValuet)
	{
		if( o!=null ){
			if( o instanceof Boolean ){
				return ((Boolean)o).booleanValue();
			}
			if( o instanceof String ){
				String s = (String)o;
				if( s.equalsIgnoreCase("true") ) 
					return true;
				if( s.equalsIgnoreCase("false") ) 
					return false;
			}
		}
		return defaulValuet;
	}
	
	/**
	 * 将对象转化为double
	 * @param o
	 * @return
	 */
	public static final double obj2double(Object o)
	{
          return obj2double(o,0D);
	}
	public static final double obj2double(Object o,double defaultValue)
	{
	    if( o instanceof Number )
			return ((Number)o).doubleValue();
		if( o instanceof String )
		{
            String s = ((String)o).trim();
			try {
				return Double.parseDouble(s);
			} catch( Exception ex )
			{
			}
		}
        return defaultValue;
	}
	/**
	 * 将对象转为为long
	 * @param o
	 * @return
	 */
	public static final long obj2long(Object o)
    {
		return obj2long(o,0);
    }
	
	public static final long obj2long(Object o,int defaultValue)
    {
        if( o instanceof Number )
            return ((Number)o).longValue();
        if( o instanceof String )
        {
            String s = ((String)o).trim();
            try {
                return Long.parseLong(s);
            } catch( Exception ex )
            {
            }
            {
                try {
                    return Double.valueOf(s).longValue();
                } catch( Exception ex )
                {
                }
            }
        }
        return defaultValue;
    }
	
	/**
	 *  判断一个字符串是否与一含通配符(*,?)的若干模式串(用逗号分开)中的一个通配(大小写敏感).
	 *  例如 like("123A45","1*B??,1*A??",true) 为true,  like("123A45","1*B??,1*A???",true) 为 false
	 *  @param text   被判断的字符串
	 *  @param patternlist  含通配符(*,?)的若干模式串(用逗号分开)
	 *  @return 是否通配, 如通配,返回 true, 否则 false
	*/
	/*public static boolean likeOneOf(String text,String pattern){
		return likeOneOf(text,pattern,false);
	}
	public static boolean likeOneOf(String text,String[] patternlist){
		return likeOneOf(text,patternlist,false);
	}*/
	public static boolean likeOneOf(String text,String... patternlist){
		if(patternlist==null) return false;
		if(patternlist.length==1 && patternlist[0].indexOf((int)',')>0)
			return likeOneOf(text,patternlist[0],false);
		else
			return likeOneOf(text,patternlist,false);
	}
	public static boolean likeOneOf(String text,String pattern,char deli){
		return likeOneOf(text,pattern,deli,(String)null,(String)null,false);
	}
	public static boolean likeOneOfN(String text,String patternlist[],boolean ignoreCase){
		return likeOneOfN(text,patternlist,null,null,ignoreCase);
	}
	public static boolean likeOneOfN(String text,String pattern,char deli,String patternPrifix,String patternSuffix,boolean ignoreCase){
        return likeOneOfN(text,splitString(pattern,deli),patternPrifix, patternSuffix,ignoreCase);
    }
    public static boolean likeOneOfN(String text,String patternlist[],String patternPrifix,String patternSuffix,boolean ignoreCase){
        if( patternPrifix==null ) patternPrifix = "";
        if( patternSuffix==null ) patternSuffix = "";
        boolean like = false;
        for(int i=0;i<patternlist.length;i++){
            String s = patternlist[i];  boolean k = true;
            if( s.length()>0 && s.charAt(0)=='~' ){
                k = false; s = s.substring(1);
            }
            if(like(text,0,patternPrifix+s+patternSuffix,0,ignoreCase)){
                like = k;
            }
        }
        return like;
    }
    
    /**
	 * 将一个字符串以某字符作为分隔符进行分隔(得到每段作为字符串的字符串数组).
	 *   "123.345.678".split("\\.");
	 *   @param  str  被分隔的字符串
	 *   @param  delimiter  分隔符
	 *   @return  分隔的结果
	*/
	public static final String[] splitString(String str,char delimiter){
        if( delimiter==0 ) return str==null? null: new String[]{ str};
		return splitString(str,0,delimiter);
	}
	
	/**
	 *   将一个字符串从某位置开始以某字符作为分隔符进行分隔(得到每段作为字符串的字符串数组).
	 *  <blockquote><pre>
	 *     String list[] = Utilities.splitString("AAAA,BBBB,CCCC,DDDDD",0,',')
	 *     // list 为  { "AAAA","BBBB","CCCC","DDDD" }
	 *   </pre></blockquote>
	 *   @param  str  被分隔的字符串
	 *   @param  istart 开始位置
	 *   @param  delimiter  分隔符
	 *   @return  分隔的结果
	*/
	public static final String[] splitString(String str,int istart,char delimiter){
		if(str==null)
			return null;
		int sl = str.length();
		int n = 0;
		for(int i=istart;i<sl;i++)
			if(str.charAt(i)==delimiter)
				n++;
		String[] sa = new String[n+1];
		int i=istart,j = 0;
		for(;i<sl;)
		{
			int iend = str.indexOf(delimiter,i);
			if(iend<0)
				break;
			sa[j++] = str.substring(i,iend);
			i = iend+1;
		}
		sa[j++] = str.substring(i);
		return sa;
	}
	public static final String[][] splitString(String str,char delimiter1,char delimiter2){
		String[] a1 = splitString(str,delimiter1);
		if( a1==null )
			return null;
		String a2[][] = new String[a1.length][];
		for(int i=0;i<a1.length;i++){
			a2[i] = splitString(a1[i],delimiter2);
		}
		return a2;
	}
	/**
	 *  判断一个字符串是否与一含通配符(*,?)的若干模式串(用逗号分开)中的一个(加上前后缀)通配.
	 *  例如 like("123A45","1*B??,1*A??",true) 为true,  like("123A45","1*B??,1*A???",true) 为 false
	 *  @param text   被判断的字符串
	 *  @param pattern  含通配符(*,?)的若干模式串(用逗号分开),
	 *  @param patternPrifix  前缀
	 *  @param patternSuffix  后缀
	 *  @param ignoreCase 是否忽略字母的大小写
	 *  @return 是否通配, 如通配,返回 true, 否则 false
	*/
	public static boolean likeOneOf(String text,String pattern,String patternPrifix,String patternSuffix,boolean ignoreCase){
		return likeOneOf(text,pattern,',',patternPrifix,patternSuffix,ignoreCase);
	}
	/**
	 *  判断一个字符串是否与一含通配符(*,?)的若干模式串(用逗号分开)中的一个(加上前后缀)通配.
	 *  例如 like("123A45","1*B??,1*A??",true) 为true,  like("123A45","1*B??,1*A???",true) 为 false
	 *  @param text   被判断的字符串
	 *  @param pattern  含通配符(*,?)的若干模式串(用deli分开),
	 *  @param deli   pattern中的分割符
	 *  @param patternPrifix  前缀
	 *  @param patternSuffix  后缀
	 *  @param ignoreCase 是否忽略字母的大小写
	 *  @return 是否通配, 如通配,返回 true, 否则 false
	*/
	public static boolean likeOneOf(String text,String pattern,char deli,String patternPrifix,String patternSuffix,boolean ignoreCase){
		if( patternPrifix==null ) patternPrifix = "";
		if( patternSuffix==null ) patternSuffix = "";
		String patternlist[] = splitString(pattern,deli);
		for(int i=0;i<patternlist.length;i++)
			if(like(text,0,patternPrifix+patternlist[i]+patternSuffix,0,ignoreCase))
				return true;
		return false;
	}
	/**
	 *  判断一个字符串是否与一含通配符(*,?)的若干模式串(用逗号分开)中的一个通配.
	 *  例如 like("123A45","1*B??,1*A??",true) 为true,  like("123A45","1*B??,1*A???",true) 为 false
	 *  @param text   被判断的字符串
	 *  @param pattern  含通配符(*,?)的若干模式串(用逗号分开)
	 *  @param ignoreCase 是否忽略字母的大小写
	 *  @return 若通配返回true否则false
	*/
	public static boolean likeOneOf(String text,String pattern,boolean ignoreCase){
		return likeOneOf(text,splitString(pattern,','),ignoreCase);
	}
	public static final boolean likeOneOf2(String[] texta,String[] patternlist,boolean ignoreCase){
		if( texta==null )
			return false;
		for(int i=0;i<texta.length;i++){
			if( likeOneOf(texta[i],patternlist,ignoreCase) )
				return true;
		}
		return false;
	}
	public static final boolean likeOneOf(String text,String[] patternlist,boolean ignoreCase){
        if( patternlist==null )
        	return false;
		for(int i=0;i<patternlist.length;i++)
			if(like(text,0,patternlist[i],0,ignoreCase))
				return true;
		return false;
	}
	/**
	 *  判断一个字符串(从某位置起)是否与一含通配符(*,?)的模式串(从某位置起)通配.例如	<br/>
	   StrUtil.like("123A456B", 0, "1*A*B", 0, false); = true		<br/>
	   StrUtil.like("123A456B", 0, "1*A???B", 0, false); = true		<br/>
	   StrUtil.like("123A456B", 0, "1*A????B", 0, false); = false	<br/>
	 *  @param text   被判断的字符串
	 *  @param oText  text的起始位置
	 *  @param pattern  含通配符(*,?)的模式串
	 *  @param oPattern  pattern的起始位置
	 *  @param ignoreCase 是否忽略字母的大小写
	 *  @return 如通配返回 true,否则false
	*/
	public static boolean like(String text,int oText,String pattern,int oPattern,boolean ignoreCase){
        if( text==null ) return pattern==null; 
		final int ltext = text.length()-oText;
		final int lpattern = pattern.length()-oPattern;
		for(int i=0;i<lpattern /*&& i<ltext*/;i++){
			char c = pattern.charAt(oPattern+i);
			if( c=='*'|| c=='%' ){
				if( i==lpattern-1 || endsWithStarsPattern(pattern,oPattern+i) )
					return true;
				for(int iText=oText+i;iText<ltext+oText;iText++)
					if(like(text,iText,pattern,oPattern+i+1,ignoreCase))
						return true;
				return false;
			}
			if( i>=ltext ) 
				return false;
            if(c=='?'||c=='_'){
                continue;
            }
			if(ignoreCase){
				if(Character.toUpperCase(c)!=Character.toUpperCase(text.charAt(oText+i)))
					return false;
			}else{
				if( c!=text.charAt(oText+i) )return false;
			}
		}
		return  ltext==lpattern || (lpattern>=ltext+1 && endsWithStarsPattern(pattern,ltext));
	}
	final private static boolean endsWithStarsPattern(String text,int from){
		if( from<0 ) from = 0;
		for(;from<text.length();from++){
			char c = text.charAt(from);
			if( c!='*' && c!='%' )return false;
		}
		return true;
	}
	
	/**
	 * a为不定维度的数组,将这个数组中所有String元素都前后去空白
	 * @param arr
	 * @return 处理后的原数组
	 */
	public static <T> T trimStrArray(T arr){
		if(arr!=null && arr.getClass().isArray()){
			Object oa[] = (Object[]) arr;
			for(int i = 0; i < oa.length; i++){
				if(oa[i] instanceof String){
					oa[i] = ((String) oa[i]).trim();
				}else{
					trimStrArray(oa[i]);
				}
			}
		}
		return arr;
	}
	/**
	 * 将c重复count次组成新字符串
	 * @param c
	 * @param count
	 * @return 新生成字符串
	 */
    public static final String newString(char c,int count){
		StringBuffer strBuffer = new StringBuffer();
		for(;count>0;count--)
			strBuffer.append(c);
		return strBuffer.toString();
    }    

}
